<template>
  <div
    class="md-editor"
    :class="{
      'md-editor--fullscreen': isFullscreen,
      'md-editor--dark': isDarkTheme
    }"
  >
    <Toolbar
      :config="toolbarConfig"
      @action="handleToolbarAction"
      @theme-change="handleThemeChange"
    />
    
    <div class="md-editor__container">
      <div
        class="md-editor__edit-area"
        :class="{ 'md-editor__edit-area--hidden': !showEditor }"
        :style="{ width: showPreview && showEditor ? '50%' : '100%' }"
      >
        <EditorArea
          ref="editorRef"
          v-model="content"
          :height="editorHeight"
          @select="handleTextSelect"
          @scroll="handleEditorScroll"
        />
      </div>
      
      <div
        class="md-editor__preview-area"
        :class="{ 'md-editor__preview-area--hidden': !showPreview }"
        :style="{ width: showPreview && showEditor ? '50%' : '100%' }"
      >
        <Preview
          ref="previewRef"
          :content="content"
          :height="editorHeight"
          :sync-scroll="syncScroll"
          @scroll="handlePreviewScroll"
        />
      </div>
    </div>
    
    <LinkDialog
      v-model="showLinkDialog"
      :initial-data="linkDialogData"
      @confirm="insertLink"
    />
    
    <ImageDialog
      v-model="showImageDialog"
      :initial-data="imageDialogData"
      @confirm="insertImage"
      @upload="handleImageUpload"
    />
    
    <!-- 表情选择器 -->
    <div v-if="showEmojiPicker" class="emoji-picker-overlay" @click="showEmojiPicker = false">
      <div class="emoji-picker-container" @click.stop>
        <EmojiPicker @select="insertEmoji" />
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted, nextTick } from 'vue';
import { useEditorStore } from '../../stores/editor';
import { useTheme } from '../../hooks/useTheme';
import Toolbar from './Toolbar.vue';
import EditorArea from './EditorArea.vue';
import Preview from './Preview.vue';
import LinkDialog from '../Dialogs/LinkDialog.vue';
import ImageDialog from '../Dialogs/ImageDialog.vue';
import EmojiPicker from '../Common/EmojiPicker.vue';
import type { ToolbarConfig, LinkDialogData, ImageDialogData } from '../../types/editor';

interface Props {
  modelValue: string;
  height?: string;
  toolbar?: ToolbarConfig;
  theme?: string;
  showPreview?: boolean;
  syncScroll?: boolean;
}

const props = withDefaults(defineProps<Props>(), {
  height: '400px',
  toolbar: () => ([
    ['heading', 'bold', 'italic', 'strikethrough'],
    ['quote', 'code', 'link', 'image', 'emoji', 'mermaid'],
    ['orderedList', 'unorderedList', 'taskList'],
    ['fullscreen', 'preview']
  ]),
  theme: 'light',
  showPreview: true,
  syncScroll: true
});

const emit = defineEmits<{
  (e: 'update:modelValue', value: string): void;
  (e: 'save', content: string): void;
  (e: 'fullscreen-change', value: boolean): void;
  (e: 'preview-change', value: boolean): void;
  (e: 'theme-change', theme: string): void;
  (e: 'image-upload', file: File): void;
  (e: 'import', data: { content: string; filename: string }): void;
  (e: 'export', data: { content: string; format: string; filename: string }): void;
}>();

// 引用子组件
const editorRef = ref<InstanceType<typeof EditorArea> | null>(null);
const previewRef = ref<InstanceType<typeof Preview> | null>(null);

// 使用 Store
const editorStore = useEditorStore();
const { currentTheme, setTheme } = useTheme();

// 本地状态
const content = ref(props.modelValue);
const isFullscreen = computed(() => editorStore.isFullscreen);
const showPreview = computed(() => editorStore.isPreviewVisible);
const showEditor = ref(true);
const syncScroll = ref(props.syncScroll);
const isDarkTheme = computed(() => currentTheme.value === 'dark');

// 对话框状态
const showLinkDialog = ref(false);
const showImageDialog = ref(false);
const showEmojiPicker = ref(false);
const linkDialogData = ref<LinkDialogData>({ text: '', url: '', title: '' });
const imageDialogData = ref<ImageDialogData>({ alt: '', url: '', title: '' });

// 计算属性
const editorHeight = computed(() => {
  return isFullscreen.value ? 'calc(100vh - 50px)' : props.height;
});

const toolbarConfig = computed(() => {
  return props.toolbar;
});

// 监听 v-model
watch(() => props.modelValue, (newVal) => {
  if (newVal !== content.value) {
    content.value = newVal;
  }
});

watch(() => content.value, (newVal) => {
  emit('update:modelValue', newVal);
  editorStore.updateContent(newVal);
});

watch(() => props.theme, (newVal) => {
  setTheme(newVal);
});

watch(isFullscreen, (newVal) => {
  emit('fullscreen-change', newVal);
});

watch(showPreview, (newVal) => {
  emit('preview-change', newVal);
});

// 处理工具栏操作
const handleToolbarAction = (action: string, level?: number) => {
  if (!editorRef.value) return;
  
  const selectedText = editorRef.value.getSelectedText();
  // console.log('Toolbar action:', action, level);
  
  switch (action) {
    // 标题处理
    case 'heading':
      // 如果直接点击标题按钮而不是下拉菜单，默认使用一级标题
      insertHeading(selectedText, level || 1);
      break;
    case 'heading-1':
      insertHeading(selectedText, 1);
      break;
    case 'heading-2':
      insertHeading(selectedText, 2);
      break;
    case 'heading-3':
      insertHeading(selectedText, 3);
      break;
    case 'heading-4':
      insertHeading(selectedText, 4);
      break;
    case 'heading-5':
      insertHeading(selectedText, 5);
      break;
    case 'heading-6':
      insertHeading(selectedText, 6);
      break;
    
    // 文本格式
    case 'bold':
      wrapText(selectedText, '**', '**');
      break;
    case 'italic':
      wrapText(selectedText, '*', '*');
      break;
    case 'strikethrough':
      wrapText(selectedText, '~~', '~~');
      break;
    
    // 块级元素
    case 'quote':
      prefixLines(selectedText, '> ');
      break;
    case 'code':
      if (selectedText.includes('\n')) {
        wrapText(selectedText, '```\n', '\n```');
      } else {
        wrapText(selectedText, '`', '`');
      }
      break;
    case 'code-block':
      wrapText(selectedText, '```\n', '\n```');
      break;
    
    // 链接和图片
    case 'link':
      openLinkDialog(selectedText);
      break;
    case 'image':
      openImageDialog();
      break;
    case 'emoji':
        toggleEmojiPicker();
        break;
      case 'mermaid':
        insertMermaidTemplate();
        break;
    
    // 列表
    case 'ordered-list':
    case 'orderedList':
      insertOrderedList(selectedText);
      break;
    case 'unordered-list':
    case 'unorderedList':
      prefixLines(selectedText, '- ');
      break;
    case 'task-list':
    case 'taskList':
      prefixLines(selectedText, '- [ ] ');
      break;
    
    // 新增功能
    case 'table':
      insertTable();
      break;
    case 'formula':
      insertFormula(selectedText);
      break;
    case 'import':
      handleImport();
      break;
    case 'export':
      handleExport(level); // level 作为导出格式参数
      break;
    case 'undo':
      handleUndo();
      break;
    case 'redo':
      handleRedo();
      break;
    
    // 编辑器控制
    case 'fullscreen':
      toggleFullscreen();
      break;
    case 'preview':
      togglePreview();
      break;
    case 'save':
      emit('save', content.value);
      break;
    
    // 默认情况
    default:
      console.warn(`未处理的工具栏操作: ${action}`);
      break;
  }
};

// 处理主题切换
const handleThemeChange = (theme: string) => {
  setTheme(theme);
  emit('theme-change', theme);
};

// 处理文本选择
const handleTextSelect = (text: string, start: number, end: number) => {
  editorStore.setSelectedText(text);
  editorStore.setCursorPosition({ start, end });
};

// 处理编辑器滚动
const handleEditorScroll = (event: Event) => {
  if (!syncScroll.value || !showPreview.value || !previewRef.value) return;
  
  const textarea = event.target as HTMLTextAreaElement;
  const { scrollTop, scrollHeight, clientHeight } = textarea;
  
  // 计算滚动比例
  const scrollRatio = scrollTop / (scrollHeight - clientHeight);
  
  // 获取预览区域的滚动信息
  const previewInfo = previewRef.value.getScrollInfo();
  const previewScrollHeight = previewInfo.scrollHeight - previewInfo.clientHeight;
  
  // 设置预览区域的滚动位置
  previewRef.value.scrollTo({
    top: previewScrollHeight * scrollRatio,
    behavior: 'auto'
  });
};

// 处理预览区域滚动
const handlePreviewScroll = (event: Event) => {
  if (!syncScroll.value || !showEditor.value || !editorRef.value) return;
  
  const preview = event.target as HTMLDivElement;
  const { scrollTop, scrollHeight, clientHeight } = preview;
  
  // 计算滚动比例
  const scrollRatio = scrollTop / (scrollHeight - clientHeight);
  
  // 获取编辑区域的元素
  const textarea = editorRef.value.$el.querySelector('textarea');
  if (!textarea) return;
  
  // 设置编辑区域的滚动位置
  const editorScrollHeight = textarea.scrollHeight - textarea.clientHeight;
  textarea.scrollTop = editorScrollHeight * scrollRatio;
};

// 处理图片上传
const handleImageUpload = (file: File) => {
  emit('image-upload', file);
};

// 工具栏操作辅助函数
const wrapText = (text: string, before: string, after: string) => {
  if (!editorRef.value) return;
  
  if (text) {
    editorRef.value.setSelectedText(`${before}${text}${after}`);
  } else {
    const placeholder = '文本';
    editorRef.value.insertText(`${before}${placeholder}${after}`);
    // 选中占位符
    const textarea = editorRef.value.$el.querySelector('textarea');
    if (textarea) {
      const cursorPos = textarea.selectionStart;
      const startPos = cursorPos - placeholder.length - after.length;
      const endPos = startPos + placeholder.length;
      
      nextTick(() => {
        textarea.setSelectionRange(startPos, endPos);
      });
    }
  }
};

const prefixLines = (text: string, prefix: string) => {
  if (!editorRef.value) return;
  
  if (text) {
    const lines = text.split('\n');
    const prefixedText = lines.map(line => `${prefix}${line}`).join('\n');
    editorRef.value.setSelectedText(prefixedText);
  } else {
    editorRef.value.insertText(`${prefix}`);
  }
};

const insertHeading = (text: string, level: number = 1) => {
  if (!editorRef.value) return;
  
  const prefix = '#'.repeat(level) + ' ';
  
  if (text) {
    editorRef.value.setSelectedText(`${prefix}${text}`);
  } else {
    editorRef.value.insertText(`${prefix}标题`);
  }
};

const insertOrderedList = (text: string) => {
  if (!editorRef.value) return;
  
  if (text) {
    const lines = text.split('\n');
    const numberedLines = lines.map((line, index) => `${index + 1}. ${line}`).join('\n');
    editorRef.value.setSelectedText(numberedLines);
  } else {
    editorRef.value.insertText('1. ');
  }
};

const openLinkDialog = (selectedText: string) => {
  linkDialogData.value = {
    text: selectedText,
    url: '',
    title: ''
  };
  showLinkDialog.value = true;
};

const insertLink = (data: LinkDialogData) => {
  if (!editorRef.value) return;
  
  let markdown = `[${data.text}](${data.url})`;
  if (data.title) {
    markdown = `[${data.text}](${data.url} "${data.title}")`;
  }
  
  editorRef.value.insertText(markdown);
};

const openImageDialog = () => {
  imageDialogData.value = {
    alt: '',
    url: '',
    title: ''
  };
  showImageDialog.value = true;
};

const insertImage = (data: ImageDialogData) => {
  if (!editorRef.value) return;
  
  let markdown = `![${data.alt}](${data.url})`;
  if (data.title) {
    markdown = `![${data.alt}](${data.url} "${data.title}")`;
  }
  
  editorRef.value.insertText(markdown);
};

const toggleFullscreen = () => {
  editorStore.toggleFullscreen();
};

const togglePreview = () => {
  editorStore.togglePreview();
};

// 新增功能实现
const insertTable = () => {
  if (!editorRef.value) return;
  
  const tableMarkdown = `
| 列1 | 列2 | 列3 |
|-----|-----|-----|
| 内容1 | 内容2 | 内容3 |
| 内容4 | 内容5 | 内容6 |
`;
  
  editorRef.value.insertText(tableMarkdown);
};

const insertFormula = (selectedText: string) => {
  if (!editorRef.value) return;
  
  const formula = selectedText || 'E = mc^2';
  const formulaMarkdown = `$$${formula}$$`;
  
  editorRef.value.insertText(formulaMarkdown);
};

const handleImport = () => {
  const input = document.createElement('input');
  input.type = 'file';
  input.accept = '.md,.markdown,.txt';
  input.onchange = (e) => {
    const file = (e.target as HTMLInputElement).files?.[0];
    if (file) {
      const reader = new FileReader();
      reader.onload = (event) => {
        const content = event.target?.result as string;
        if (content) {
          emit('update:modelValue', content);
          emit('import', { content, filename: file.name });
        }
      };
      reader.readAsText(file);
    }
  };
  input.click();
};

const handleExport = async (format: string) => {
  const exportContent = content.value;
  const timestamp = new Date().toISOString().slice(0, 19).replace(/:/g, '-');
  const filename = `markdown-export-${timestamp}`;
  
  switch (format) {
    case 'md':
      downloadFile(exportContent, `${filename}.md`, 'text/markdown');
      break;
    case 'html':
      const htmlContent = convertMarkdownToHtml(exportContent);
      downloadFile(htmlContent, `${filename}.html`, 'text/html');
      break;
    case 'pdf':
      await exportToPdf(exportContent, filename);
      break;
    default:
      console.warn(`不支持的导出格式: ${format}`);
  }
  
  emit('export', { content: exportContent, format, filename });
};

const downloadFile = (content: string, filename: string, mimeType: string) => {
  const blob = new Blob([content], { type: mimeType });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = filename;
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
  URL.revokeObjectURL(url);
};

const convertMarkdownToHtml = (markdown: string): string => {
  // 简单的markdown到HTML转换，实际项目中应该使用专门的库
  const htmlTemplate = `<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Exported Document</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.css">
  <` + `style>
    body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }
    h1, h2, h3, h4, h5, h6 { color: #333; }
    code { background: #f4f4f4; padding: 2px 4px; border-radius: 3px; }
    pre { background: #f4f4f4; padding: 10px; border-radius: 5px; overflow-x: auto; }
    blockquote { border-left: 4px solid #ddd; margin: 0; padding-left: 20px; color: #666; }
    table { border-collapse: collapse; width: 100%; }
    th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
    th { background-color: #f2f2f2; }
  </` + `style>
</head>
<body>
  <pre>${markdown}</pre>
</body>
</html>`;
  return htmlTemplate;
};

// PDF导出功能
const exportToPdf = async (markdown: string, filename: string) => {
  try {
    const { jsPDF } = await import('jspdf');
    const html2canvas = (await import('html2canvas')).default;
    
    // 获取预览组件的渲染内容
    const previewElement = document.querySelector('.md-preview__content');
    if (!previewElement) {
      throw new Error('预览内容未找到');
    }
    
    // 创建临时HTML元素，复制预览内容的样式和内容
    const tempDiv = document.createElement('div');
    tempDiv.innerHTML = previewElement.innerHTML;
    
    // 应用样式
    tempDiv.style.position = 'absolute';
    tempDiv.style.left = '-9999px';
    tempDiv.style.width = '800px';
    tempDiv.style.padding = '20px';
    tempDiv.style.backgroundColor = 'white';
    tempDiv.style.color = '#333';
    tempDiv.style.fontFamily = '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif';
    tempDiv.style.fontSize = '14px';
    tempDiv.style.lineHeight = '1.6';
    
    // 复制预览样式到临时元素
    const previewStyles = window.getComputedStyle(previewElement);
    const stylesToCopy = ['font-family', 'font-size', 'line-height', 'color'];
    stylesToCopy.forEach(prop => {
      tempDiv.style.setProperty(prop, previewStyles.getPropertyValue(prop));
    });
    
    // 添加代码高亮样式
    const styleElement = document.createElement('style');
    styleElement.textContent = `
      .hljs {
        background: #f8f8f8 !important;
        color: #333 !important;
        border-radius: 6px;
        padding: 16px;
        font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
        font-size: 14px;
        line-height: 1.5;
        overflow-x: auto;
      }
      h1, h2, h3, h4, h5, h6 {
        margin-top: 24px;
        margin-bottom: 16px;
        font-weight: 600;
        line-height: 1.25;
      }
      h1 { font-size: 2em; border-bottom: 1px solid #eaecef; padding-bottom: 10px; }
      h2 { font-size: 1.5em; border-bottom: 1px solid #eaecef; padding-bottom: 8px; }
      h3 { font-size: 1.25em; }
      h4 { font-size: 1em; }
      h5 { font-size: 0.875em; }
      h6 { font-size: 0.85em; color: #6a737d; }
      p { margin-bottom: 16px; }
      blockquote {
        padding: 0 1em;
        color: #6a737d;
        border-left: 0.25em solid #dfe2e5;
        margin: 0 0 16px 0;
      }
      table {
        border-collapse: collapse;
        width: 100%;
        margin-bottom: 16px;
      }
      th, td {
        border: 1px solid #dfe2e5;
        padding: 6px 13px;
        text-align: left;
      }
      th {
        background-color: #f6f8fa;
        font-weight: 600;
      }
      code:not(.hljs) {
        background: #f1f3f4;
        color: #d73a49;
        padding: 2px 4px;
        border-radius: 3px;
        font-family: 'Monaco', 'Menlo', monospace;
        font-size: 0.9em;
      }
      ul, ol {
        margin-bottom: 16px;
        padding-left: 2em;
      }
      li {
        margin-bottom: 4px;
      }
    `;
    tempDiv.appendChild(styleElement);
    
    document.body.appendChild(tempDiv);
    
    // 等待渲染完成
    await new Promise(resolve => setTimeout(resolve, 200));
    
    // 转换为canvas
    const canvas = await html2canvas(tempDiv, {
      scale: 2,
      useCORS: true,
      allowTaint: true,
      backgroundColor: '#ffffff',
      logging: false
    });
    
    // 移除临时元素
    document.body.removeChild(tempDiv);
    
    // 创建PDF
    const imgData = canvas.toDataURL('image/png');
    const pdf = new jsPDF({
      orientation: 'portrait',
      unit: 'mm',
      format: 'a4'
    });
    
    const imgWidth = 210; // A4宽度
    const pageHeight = 295; // A4高度
    const imgHeight = (canvas.height * imgWidth) / canvas.width;
    let heightLeft = imgHeight;
    
    let position = 0;
    
    // 添加第一页
    pdf.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
    heightLeft -= pageHeight;
    
    // 如果内容超过一页，添加更多页面
    while (heightLeft >= 0) {
      position = heightLeft - imgHeight;
      pdf.addPage();
      pdf.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
      heightLeft -= pageHeight;
    }
    
    // 下载PDF
    pdf.save(`${filename}.pdf`);
  } catch (error) {
    console.error('PDF导出失败:', error);
    alert('PDF导出失败，请稍后重试');
  }
};

// 撤销重做功能（简单实现）
const history = ref<string[]>([]);
const historyIndex = ref(-1);

const addToHistory = (content: string) => {
  // 移除当前位置之后的历史记录
  history.value = history.value.slice(0, historyIndex.value + 1);
  // 添加新的历史记录
  history.value.push(content);
  historyIndex.value = history.value.length - 1;
  
  // 限制历史记录数量
  if (history.value.length > 50) {
    history.value.shift();
    historyIndex.value--;
  }
};

const handleUndo = () => {
  if (historyIndex.value > 0) {
    historyIndex.value--;
    const previousContent = history.value[historyIndex.value];
    content.value = previousContent;
    emit('update:modelValue', previousContent);
  }
};

const handleRedo = () => {
  if (historyIndex.value < history.value.length - 1) {
    historyIndex.value++;
    const nextContent = history.value[historyIndex.value];
    content.value = nextContent;
    emit('update:modelValue', nextContent);
  }
};

// 监听内容变化，添加到历史记录
watch(() => content.value, (newVal, oldVal) => {
  if (newVal !== oldVal && oldVal !== undefined) {
    addToHistory(oldVal);
  }
}, { flush: 'post' });

// 公开方法
const focus = () => {
  editorRef.value?.focus();
};

const insertText = (text: string) => {
  editorRef.value?.insertText(text);
};

const getContent = () => {
  return content.value;
};

// 表情相关方法
const toggleEmojiPicker = () => {
  showEmojiPicker.value = !showEmojiPicker.value;
};

const insertEmoji = (emoji: { code: string; char: string; name: string }) => {
  if (!editorRef.value) return;
  
  // 插入表情符号
  editorRef.value.insertText(emoji.char);
  
  // 关闭表情选择器
  showEmojiPicker.value = false;
  
  // 聚焦编辑器
  nextTick(() => {
    editorRef.value?.focus();
  });
};

// Mermaid图表相关方法
const insertMermaidTemplate = () => {
  const template = `\n\`\`\`mermaid\ngraph TD\n    A[开始] --> B{判断条件}\n    B -->|是| C[执行操作1]\n    B -->|否| D[执行操作2]\n    C --> E[结束]\n    D --> E\n\`\`\`\n`;
  insertText(template);
  editorRef.value?.focus();
};

// 初始化
onMounted(() => {
  // 初始化编辑器状态
  editorStore.updateContent(content.value);
  setTheme(props.theme);
});

// 暴露方法
defineExpose({
  focus,
  insertText,
  getContent
});
</script>

<style lang="scss" scoped>
.md-editor {
  width: 100%;
  height: 100%;
  border: 1px solid var(--md-borderColor, #e0e0e0);
  border-radius: 4px;
  background-color: var(--md-backgroundColor, #ffffff);
  color: var(--md-textColor, #333333);
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
  
  &--dark {
    background-color: var(--md-backgroundColor, #1e1e1e);
    color: var(--md-textColor, #e0e0e0);
  }
  
  &--fullscreen {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 9999;
    border-radius: 0;
    border: none;
  }
  
  &__container {
    display: flex;
    position: relative;
  }
  
  &__edit-area,
  &__preview-area {
    transition: width 0.3s ease;
    
    &--hidden {
      display: none;
    }
  }
}

// 表情选择器样式
.emoji-picker-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.3);
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
}

.emoji-picker-container {
  position: relative;
  z-index: 1001;
}
</style>